home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Ham⁄GPS / SoftKiss.src.1.8 Folder / SoftKiss.src.1.8 / core / sfk_core_scc_init.c < prev    next >
Text File  |  1993-03-12  |  4KB  |  159 lines

  1. /*
  2.  * SoftKiss scc setup/unitialize routines
  3.  * for use by code inside the device driver.
  4.  * by Aaron Wohl / N3LIW (aw0g+@andrew.cmu.edu) jul 1990
  5.  * 6393 Penn Ave #303
  6.  * Pittsburgh PA, 15206
  7.  * work: (412)-268-5032
  8.  * home: (412)-731-6159
  9.  */
  10.  
  11. #include "sfk_core.h"
  12. #include "sfk_core_private.h"
  13. #include "8530.h"
  14.  
  15. #define sfk_bCtl 0                /*offset from SCCRd or SCCWr to b control port*/
  16. #define sfk_bData 4                /*offset from SCCRd or SCCWr to b data port*/
  17. #define sfk_aCtl 2                /*offset from SCCRd or SCCWr to a control port*/
  18. #define sfk_aData 6                /*offset from SCCRd or SCCWr to a data port*/
  19.  
  20. #define sfk_xCtl 0                /*offset for interpt routine to control*/
  21. #define sfk_xData 4
  22.  
  23. #define sfk_END_OF_SCC_LIST (0x0FF)
  24.  
  25. /*
  26.  * shutdown port (undo scc_init values)
  27.  * this list has all reset values except the actual reset
  28.  * command.  the reset command is written to port 9 wich is
  29.  * not duplicated but actuallyt the same register for A and B.
  30.  */
  31. static uint8 sfk_scc_uninit[]={
  32.  R10,0x00,            /*flag under (no abort), flag idle (no abort*/
  33.  R0,RES_EXT_INT,    /*reset ext/sts interrupts*/
  34.  R15,DCDIE,            /*enable DCD interrupt (used by the mouse driver)*/
  35.  R1,EXT_INT_ENAB,    /*no receive interrupts, just external interrupts*/
  36.  R5,0x00,            /*stop tx, lower dtr*/
  37.  sfk_END_OF_SCC_LIST,sfk_END_OF_SCC_LIST
  38. };
  39.  
  40. /*
  41.  * set buad rate regiser for the passed divider
  42.  * due to a hardware bug (see amd scc manual)
  43.  * we can't stop the divider while we do this
  44.  */
  45. static void sfk_scc_set_buad_divider(sfk_prt_pt p,uint16 divider)
  46. {
  47.     uint8 high=divider>>8;
  48.     uint8 low=divider;
  49.     if((sfk_read_scc(p,R13)==high)&&
  50.         (sfk_read_scc(p,R12)==low))
  51.             return;
  52.     /* choose write order to mimimize long count if underflow
  53.      * happens between writes and don't make a zero br divider
  54.      */
  55.     if(high!=0) {
  56.         sfk_write_scc(p,R13,high);
  57.         sfk_write_scc(p,R12,low);
  58.     } else {
  59.         sfk_write_scc(p,R12,low);
  60.         sfk_write_scc(p,R13,high);
  61.     }
  62.         
  63. }
  64.  
  65. /*
  66.  * set divider for proper rate to transmit
  67.  * need to wait one underflow to pick up proper rate
  68.  */
  69. void sfk_scc_set_buad_divider_xmit(sfk_prt_pt p)
  70. {
  71.     sfk_scc_set_buad_divider(p,p->sfk_IVAR(xmit_rate_divider));
  72. }
  73.  
  74. /*
  75.  * set divider for proper rate to recieve
  76.  * need to wait one underflow to pick up proper rate
  77.  */
  78. void sfk_scc_set_buad_divider_recv(sfk_prt_pt p)
  79. {
  80.     sfk_scc_set_buad_divider(p,p->sfk_IVAR(recv_rate_divider));
  81. }
  82.  
  83. static void sfk_scc_wrt_ctl_list(p,data_list)
  84. sfk_prt_pt p;
  85. register uint8 *data_list;
  86. {
  87.     register uint8 register_number;
  88.      while((register_number=*data_list++)!=sfk_END_OF_SCC_LIST)
  89.          sfk_write_scc(p,register_number,*data_list++);
  90. }
  91.  
  92. static void extra_delay_for_scc_reset()
  93. {
  94.     register long i=40;    /*should be fast enough on any speed processor*/
  95.     while(i-- > 0)
  96.         ;
  97. }
  98.  
  99. static int sfk_scc_reset_val[2]={0x4a,0x8a};
  100. void sfk_reset_scc(sfk_prt_pt p)
  101. {
  102.     sfk_write_scc(p,R9,sfk_scc_reset_val[p->pnum]);
  103.     extra_delay_for_scc_reset();
  104.     sfk_scc_wrt_ctl_list(p,sfk_scc_uninit);
  105. }
  106.  
  107. /*
  108.  * initilize the scc chip port sdlc
  109.  */
  110. static uint8 sfk_scc_init[]={
  111.   R4,0x20,    /*x1 clock, SDLC mode, syncronious mode, no parity*/
  112.   R1,0x13,    /*interupt on any char tx and external*/
  113.   R15,SYNCIE|DCDIE,    /*interupt on zc sync*/
  114.   R3,0xcb,    /*Rx 8 bits/char, hunt mode, Rx CRC on, Rx on*/
  115.   R5,0x61,    /*8 bits/char dtr low,rts low, crc16*/
  116.   R6,0x7e,    /*we are sdlc address zero*/
  117.   R7,0x7e,    /*sync character is 7e*/
  118.   R10,0xa0,    /*CRC preset, NRZI mode, 8 bit sync,abort underun*/
  119.   R11,0x70,    /*receive clk is DPLL, TR clk is BR gen*/
  120.   R14,0x81,    /*dpll source is br*/
  121.   R14,0xe1,    /*NRZI mode, baud generator off*/
  122.  
  123.   R14,0x21,    /*enter search mode, turn on transmit BR*/
  124.   R3,0xdb,    /*Rx 8 bits/char, hunt mode, Rx CRC on, Rx on*/
  125.   R0,0x10,    /*reset external ints*/
  126.   R0,0x10,
  127.  
  128.   sfk_END_OF_SCC_LIST,sfk_END_OF_SCC_LIST    /*terminate list*/
  129. };
  130.  
  131. /*
  132.  * setup pointers to registers
  133.  */
  134. void sfk_init_register_addresses(sfk_prt_pt p)
  135. {
  136.     if(p->pnum==0)    {
  137.         p->ctl_rd=((uint8*)SCCRd)+sfk_bCtl;
  138.         p->ctl_wr=((uint8*)SCCWr)+sfk_bCtl;
  139.         p->data_rd=((uint8*)SCCRd)+sfk_bData;
  140.         p->data_wr=((uint8*)SCCWr)+sfk_bData;
  141.     } else {
  142.         p->ctl_rd=((uint8*)SCCRd)+sfk_aCtl;
  143.         p->ctl_wr=((uint8*)SCCWr)+sfk_aCtl;
  144.         p->data_rd=((uint8*)SCCRd)+sfk_aData;
  145.         p->data_wr=((uint8*)SCCWr)+sfk_aData;
  146.     }
  147. }
  148.  
  149. /*
  150.  * initialize the scc for normal operation
  151.  */
  152. void sfk_setup_scc(sfk_prt_pt p)
  153. {
  154.     sfk_reset_scc(p);
  155.     sfk_scc_set_buad_divider_recv(p);
  156.     sfk_scc_wrt_ctl_list(p,sfk_scc_init);
  157. }
  158.  
  159.